<?php
class DBUpdater extends MultiCurl
{
    const SERIA = 'series';
    const EPISODE = 'episodes';

    const CACHE_PATH = './temp/dbupdater/';

	private $tv;

	private $updateslist = array();

	private $updated;

	private $last_time;
	private $new_time;

	private $cache_file;
	private $gettingFromCache = false;

	public function __construct()
	{
		$this->tv = new TheTvDB;
		$this->tv->getApi()->enableDebug();

		$this->updated = array(self::SERIA => array(), self::EPISODE => array());
		$this->cache_file = self::CACHE_PATH . date('Y-m-d') . '.xml';

    @ini_set('max_execution_time', 600);
	}

	public function update()
	{
	    try {
		    $this->last_time = $this->tv->getApi()->getPreviousTime();

		    $this->updateslist = $this->getUpdateList();
		    if (!$this->gettingFromCache) {
                $this->saveCache($this->updateslist, $this->cache_file);
		    } else {
		        echo '**Update list retrieved from cache file:** ' . $this->cache_file . PHP_EOL . PHP_EOL;
		    }

    	    $api = $this->tv->getApi();
    	    foreach ($this->updateslist[self::SERIA] as $seria_id) {
                if ($this->tv->isSeriaIsset($seria_id)) {
                    $url = $api->getLinkForZip($seria_id);
                    $tempPath = self::CACHE_PATH . 'seria_' . $seria_id . '.zip';
                    $this->addZipUrl($url, $tempPath);
    	        }
            }

            $this->wait();

    		$api->setPreviousTime($this->updateslist['servertime']);
    		$this->new_time = $this->updateslist['servertime'];
		} catch (Exception $e) {
		    echo $e->getMessage();
		}

		if (file_exists($this->cache_file)) {
	        unlink($this->cache_file);
		}
	}

    protected function onLoad ($url, $content, $info, $filepath)
    {
        $time = $info['total_time'];
        $this->tv->getApi()->addRequest($url, $time);

        $epIdList = $this->updateslist[self::EPISODE];

        $data = $this->tv->getApi()->loadSeriaAllData(-1, tvapi::SERIA | tvapi::EPISODES, $filepath);
        $seriaData = $data['seria'];
        $epsData = array();
        foreach ($data['episodes'] as $episode) {
            if (in_array($episode['id'], $epIdList)) {
                $epsData[] = $episode;
            }
        }

        try {
	        $seriaInsert = $this->tv->insertSeria($seriaData);
            if (!empty($epsData)) {
	            $epsInsert = $this->tv->insertEpisodes($epsData);
            } else {
                $epsInsert = array();
            }

		    //echo "A\t{$type}: {$data['id']}" . PHP_EOL;
		    $this->updated[self::SERIA][] = $seriaInsert['id'];
		    foreach ($epsInsert as $ep) {
		        $this->updated[self::EPISODE][] = $ep['id'];
		    }
	    }
        catch (Exception $e) {
            echo "E\t{$url}: " . $e->getMessage() . PHP_EOL;
        }
    }

	private function getUpdateList()
	{
	    if (file_exists($this->cache_file)) {
	        $list = $this->checkCache();
	    } else {
	        $list = $this->tv->getApi()->loadUpdatesList();
	    }

	    return $list;
	}

	/**
	 * @param string $type DBUpdater::SERIA vagy DBUpdater::EPISODE
	 * @param string $mode updated vagy skipped
	 */
	public function getResult($type = '')
	{
	    if ($type != '') {
	        if (isset($this->updated[$type])) {
	            return $this->updated[$type];
	        } else {
	            return false;
	        }
	    } else {
	        return $this->updated;
	    }
	}

	private function saveCache($list, $location)
	{
	    $xml = '<?xml version="1.0" encoding="UTF-8" ?>' . PHP_EOL;
	    $xml .= '<Items>' . PHP_EOL;
	    $xml .= '<Time>' . $list['servertime'] . '</Time>' . PHP_EOL;
	    foreach ($list['series'] as $seriaId) {
	        $xml .= '<Series>' . $seriaId . '</Series>' . PHP_EOL;
	    }
	    foreach ($list['episodes'] as $epId) {
	        $xml .= '<Episode>' . $epId . '</Episode>' . PHP_EOL;
	    }
	    $xml .= '</Items>';

	    return file_put_contents($location, $xml);
	}

	public function checkCache($year = null, $month = null, $day = null)
	{
	    if ($year === null) {
	        $filename = $this->cache_file;
	    } else {
	        $filename = self::CACHE_PATH . sprintf('%4d-%02d-%02d.xml', $year, $month, $day);
	    }

	    $list = $this->tv->getApi()->loadUpdatesList(0, $filename);

	    $day = 60*60*24;
	    $oneDayAgo = time() - $day;

	    $needUpdate = array(
	        'servertime' => $list['servertime'],
	    	'series' => $list['series'], //array()
	        'episodes' => $list['episodes'] //array()
	    );

	    $series = $this->tv->getSeriesByIds($list['series']);
	    foreach ($series as $seria) {
            if (strtotime($seria['last_updated']) <= $oneDayAgo) {
	            $needUpdate['series'][] = $seria['id'];
	        }
	    }

	    $episodes = $this->tv->getEpisodesByIds($list['episodes']);
	    foreach ($list['episodes'] as $epId) {
	        if (isset($episodes[$epId]) && strtotime($episodes[$epId]['last_updated']) >= $oneDayAgo) {
	            continue;
	        }
	        $needUpdate['episodes'][] = $epId;
	    }

	    $this->gettingFromCache = true;
	    return $needUpdate;
	}

    public function debug()
	{
	    echo PHP_EOL . '-======= ' . __METHOD__ . ' start =======-' . PHP_EOL;

	    echo "Last saved prevtime:\t" . $this->last_time .
	    ' (' . date('Y.m.d H:i:s', $this->last_time) . ')' . PHP_EOL;
	    echo "Received prevtime:\t" . $this->new_time .
	    ' (' . date('Y.m.d H:i:s', $this->new_time) . ')' . PHP_EOL;
	    $saved = $this->tv->getApi()->getPreviousTime();
	    echo "Saved prevtime:\t\t" . $saved .
	    ' (' . date('Y.m.d H:i:s', $saved) . ') --->';
	    echo $this->new_time == $saved ? '**OK**' :  '**FAIL**';

	    echo PHP_EOL . PHP_EOL;

	    $seriesOnList = $this->updateslist[self::SERIA];
	    $episodesOnList =  $this->updateslist[self::EPISODE];
	    $seriesSkipped = array_diff($seriesOnList, $this->updated[self::SERIA]);
	    $episodesSkipped = array_diff($episodesOnList, $this->updated[self::EPISODE]);
	    printf('SeriesOnList: %d (%d skipped)' . PHP_EOL, count($seriesOnList), count($seriesSkipped));
	    printf('EpisodesOnList: %d (%d skipped)' . PHP_EOL, count($episodesOnList), count($episodesSkipped));

	    echo PHP_EOL;

	    $updatedSeries = $this->getResult(self::SERIA);
	    $sDbData = $this->tv->getSeriesByIds($updatedSeries, true);

	    $updatedEpisodes = $this->getResult(self::EPISODE);
	    $eDbData = $this->tv->getEpisodesByIds($updatedEpisodes, true);

	    foreach ($updatedSeries as $sId) {
	        if (isset($sDbData[$sId])) {
	            $seriaData = $sDbData[$sId];
	            printf('Sorozat: %s#%d frissítve (%s), %s' . PHP_EOL,
	                   $seriaData['seriesname'], $sId, $seriaData['last_updated'],
	                   nicetime($seriaData['last_updated']));
	        } else {
	            echo '**HIBA** Sorozat ('.$sId.') nem található az adatbázisban!' . PHP_EOL;
	        }
	    }
	    echo PHP_EOL;
	    foreach ($updatedEpisodes as $eId) {
	        if (isset($eDbData[$eId])) {
	            $epData = $eDbData[$eId];
	            printf('Epizód: %s-%s#%d frissítve (%s), %s' . PHP_EOL,
	                   $epData['seriesname'], $epData['episodename'], $eId,
	                   $epData['last_updated'], nicetime($epData['last_updated']));
	        } else {
	            echo '**HIBA** Epizód ('.$eId.') nem található az adatbázisban!' . PHP_EOL;
	        }
	    }

	    echo PHP_EOL;

        $skippedEps = $this->tv->getEpisodesByIds($episodesSkipped, true);
        echo 'SkipCheck:' . PHP_EOL;
        if (!empty($skippedEps)) {
            foreach ($skippedEps as $sEp) {
                printf('**WARNING** %s-%s(%d) kihagyva, pedig benne van a db-ben!' . PHP_EOL,
                    $sEp['seriesname'], $sEp['episodename'], $sEp['id']);
            }
        } else {
            echo '**OK** Nem maradt ki olyan epizód, ami a db-ben benne lenne.' . PHP_EOL;
        }

	    echo PHP_EOL;

	    $requests = $this->tv->getApi()->getRequests();
        echo 'TheTvDb API kérések:' . PHP_EOL;
        echo 'RequestCount: ' . count($requests) . PHP_EOL;
        echo 'RequestTotalTime: ' . $this->tv->getApi()->getRequestsTotalTime() . PHP_EOL;
        foreach ($requests as $request) {
            printf('%s: %s secs' . PHP_EOL, $request['url'], $request['time']);
        }
	    echo PHP_EOL . '-======= ' . __METHOD__ . ' end =======-' . PHP_EOL;
	}
}
?>